package com.yenlien.traceyun.business.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.util.Md5Utils;
import com.yenlien.traceyun.business.bean.RestURL;
import com.yenlien.traceyun.business.dao.*;
import com.yenlien.traceyun.business.entity.*;
import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import com.yenlien.traceyun.business.service.BaseSoilService;
import com.yenlien.traceyun.business.service.CompanyShowService;
import com.yenlien.traceyun.business.service.ScanRecordService;
import com.yenlien.traceyun.business.service.rest.control.ModelCropRestService;
import com.yenlien.traceyun.business.service.rest.usercenter.CompanyRestService;
import com.yenlien.traceyun.common.utils.HttpUtil;
import com.yenlien.traceyun.webase.controller.BaseController;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: bigwangy@sina.com
 * @create: 2020-12-07
 * @description: 扫码接口
 **/

@RestController
@RequestMapping("/traceinfo")
public class TraceInfoController extends BaseController {

    @Autowired
    private CodeInfoDao codeInfoDao;

    @Autowired
    private SubpackageDao subpackageDao;

    @Autowired
    private BoxDao boxDao;

    @Autowired
    private ProcessDetailDao processDetailDao;

    @Autowired
    private CompanyRestService companyRestService;

    @Autowired
    private ScanRecordService scanRecordService;

    @Autowired
    private ProductDao productDao;

    @Autowired
    private CompanyShowService companyShowService;

    @Autowired
    private BaseSoilService baseSoilService;

    @Autowired
    private EquipmentDao equipmentDao;

    @Autowired
    private BaseSoilEquipmentDao baseSoilEquipmentDao;

    @Autowired
    private ModelCropRestService modelCropRestService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ProcessPlanDao processPlanDao;

    @Autowired
    private ProcessMaterialsDao processMaterialsDao;

    @Autowired
    private StorageManageDao storageManageDao;
    @Autowired
    private DetectionDao detectionDao;

    /**
     * 根据二维码查询扫码信息
     *
     * @param code
     * @param request
     * @return
     */
    @GetMapping(value = "/scan/code/{code}")
    public Object scan(@PathVariable() String code, HttpServletRequest request) {
        Box box = boxDao.findBySourceCode(code);
        if (box == null) {
            throw new BusinessException("500", "追溯信息不存在或者未激活");
        }
        JSONObject result = new JSONObject();
        List<String> contents = new ArrayList<>();
        List<CodeInfo> codeInfos = codeInfoDao.findByCode(box.getSubpackageBatch());
        if (codeInfos == null || codeInfos.size() == 0) {
            throw new BusinessException("500", "追溯信息不存在或者未激活");
        } else {
            String baseSoilId = "";
            for (CodeInfo info : codeInfos) {
                // 没有productId （扫码无法正常显示） 在此处加上 2022-5-20
                JSONArray jsonArray = JSONObject.parseArray(info.getContent());
                for(Object arr : jsonArray){
                    JSONObject jsonObject = (JSONObject) arr;
                    if("processDetail".equals(jsonObject.getString("step"))){
                        String processDetailId = jsonObject.getJSONObject("info").getString("id");
                        ProcessDetail processDetail = processDetailDao.findById(processDetailId);
                        if(StringUtils.isBlank(processDetail.getProductId())){
//                            throw new BusinessException("未绑定产品, processDetailId: " + processDetailId);
                            throw new BusinessException("未绑定产品, 请在加工管理页面关联产品");
                        }
                        jsonObject.getJSONObject("info").put("productId", processDetail.getProductId());
                        break;
                    }
                }
                contents.add(JSONObject.toJSONString(jsonArray));
                result.put("branch", info.getBranch());
                baseSoilId = getBaseSoilId(info);
            }
            if (StringUtils.isNotBlank(baseSoilId)) {
                List<Equipment> equipmentList = new ArrayList<>();
                List<BaseSoilEquipment> equipmentByMassifId = baseSoilEquipmentDao.getEquipmentByMassifId(baseSoilId);
                for (BaseSoilEquipment base : equipmentByMassifId) {
                    Equipment equipment = equipmentDao.findById(base.getEquipmentId());
                    equipment.setCoordinate(base.getCoordinate());
                    equipment.setBaseSoil(base.getBaseSoilId());
                    equipmentList.add(equipment);
                }
                if (!CollectionUtils.isEmpty(equipmentList)) {
                    for (Equipment equipment : equipmentList) {
                        if (StringUtils.isNotBlank(equipment.getAppKey()) && StringUtils.isNotBlank(equipment.getAppSecret())) {
                            // 获取token
                            Map<String, String> map = new HashMap<>();
                            map.put("appKey", equipment.getAppKey());
                            map.put("appSecret", equipment.getAppSecret());
                            String result2 = HttpUtil.post("https://open.ys7.com/api/lapp/token/get", map);
                            String accessToken = JSONObject.parseObject(JSONObject.parseObject(result2).get("data").toString()).get("accessToken").toString();
                            equipment.setAccessToken(accessToken);
                        }
                    }
                }
                result.put("equipments", equipmentList);
            }
            String lastStep = getLastStep(codeInfos.get(0));
            if (StringUtils.isNotBlank(lastStep)) {
                Object data = restTemplate.getForObject(RestURL.PLANTURL + "detection/findByRelevanceId/" + lastStep, JSONObject.class).get("data");
                result.put("detection", data);
            }
            result.put("infos", contents);
        }
        result.put("company", companyRestService.findById(box.getCompanyId()));
        result.put("code", Md5Utils.getMD5(code, "UTF-8"));
        scanRecordService.save(request, code, box.getCompanyId());
        return result;
    }

    // 生产系统扫码页接口
    @GetMapping(value = "/pscan/code/{code}")
    public Object produceScan(@PathVariable() String code, HttpServletRequest request) {
        Box box = boxDao.findBySourceCode(code);
        if (box == null) {
            throw new BusinessException("500", "追溯信息不存在或者未激活");
        }
        JSONObject result = new JSONObject();
        // 查询分包数据
        Subpackage subpackage = subpackageDao.findById(box.getSubpackageId());

        // 查询生产管理数据
        ProcessDetail processDetail = processDetailDao.findById(subpackage.getRelevanceId());
        // 生产计划
        ProcessPlan processPlan = processPlanDao.findById(processDetail.getProcessPlanId());
        // 生产原料
        List<ProcessMaterials> processMaterialsList = processMaterialsDao.findByProcessPlanId(processPlan.getId());
        // 仓储
        List<StorageManage> storageManageList = storageManageDao.findByBatchList(processMaterialsList.stream().map(ProcessMaterials::getMaterialBatch).collect(Collectors.toList()), box.getCompanyId());
        // 确定原料是溯源入库还是非溯源入库
        for(ProcessMaterials processMaterials : processMaterialsList){
            for(StorageManage storageManage : storageManageList){
                if(processMaterials.getMaterialBatch().equals(storageManage.getBatch())){
                    if("0".equals(storageManage.getPurchaseType())){
                        processMaterials.setFlag("0");
                        processMaterials.setSourceCode(storageManage.getSourceCode());
                    }else {
                        processMaterials.setFlag("1");
                    }
                }
            }
        }

        // 检测
        List<Detection> detectionList = detectionDao.findByRelevanceIdList(storageManageList.stream().map(StorageManage::getId).collect(Collectors.toList()));

        Product product = null;
        if(StringUtils.isNotBlank(processDetail.getProductId())){
            product = productDao.findById(processDetail.getProductId());
        }

        result.put("subpackage", subpackage);       // 分包数据
        result.put("processDetail", processDetail); // 生产管理
        result.put("processPlan", processPlan);     // 生产计划
        result.put("processMaterialsList", processMaterialsList);   // 原料
        result.put("storageManageList", storageManageList);         // 仓储
        result.put("detectionList", detectionList);                 // 检测
        result.put("code", Md5Utils.getMD5(code, "UTF-8")); // 区块链
        scanRecordService.save(request, code, box.getCompanyId());
        result.put("company", companyRestService.findById(box.getCompanyId()));
        result.put("scanInfo", scan(scanRecordService.findByCodeAndCompanyId(code, box.getCompanyId())));
        result.put("product", product);     // 产品信息
        return result;
    }

    public JSONObject scan(List<ScanRecord> scanRecordList){
        JSONObject object = new JSONObject();
        object.put("firstScanRecords", scanRecordList.get(0));  // 首次扫码记录
        object.put("countScan", scanRecordList.size());  // 总共扫码次数
        Map<String, List<ScanRecord>> listMap = scanRecordList.stream().collect(Collectors.groupingBy(ScanRecord::getAddress));
        List<JSONObject> jsonObjects = new ArrayList<>();
        for(String key : listMap.keySet()){
            JSONObject json = new JSONObject();
            json.put("address", key);
            json.put("num", listMap.get(key).size());
            jsonObjects.add(json);
        }
        object.put("scanRecords", jsonObjects);  // 扫码记录统计
        return object;
    }


//    /**
//     * 根据二维码查询扫码信息
//     * @param code
//     * @param request
//     * @return
//     */
//    @GetMapping(value = "/scan/code/{code}")
//    public Object scan1(@PathVariable()String code, HttpServletRequest request){
//        Box box = boxDao.findBySourceCode(code);
//        if(box==null){
//            throw new BusinessException("500","追溯信息不存在或者未生成");
//        }
//        JSONObject result = new JSONObject();
//        List<String> contents = new ArrayList<>();
//        List<CodeInfo> codeInfos = codeInfoDao.findByCode(box.getSubpackageBatch());
//        if(codeInfos==null || codeInfos.size()==0){
//            throw new BusinessException("500","追溯信息不存在或者未生成");
//        }else{
//            for(CodeInfo info:codeInfos){
//                contents.add(info.getContent());
//                result.put("branch",info.getBranch());
//            }
//            result.put("infos",contents);
//        }
//        result.put("company",companyRestService.findById(box.getCompanyId()));
//        scanRecordService.save(request, code,box.getCompanyId());
//        return result;
//    }


    public String getBaseSoilId(CodeInfo info) {
        // 获取地块ID
        String baseSoilId = "";
        if (info.getContent().contains("basesoil")) {
            JSONArray jsonArray = JSONObject.parseArray(info.getContent());
            int size = jsonArray.size();
            for (int i = 0; i < size; i++) {
                String step = jsonArray.getJSONObject(i).get("step").toString();
                if ("basesoil".equals(step)) {
                    baseSoilId = JSONObject.parseObject(jsonArray.getJSONObject(i).get("info").toString()).get("id").toString();
                }
            }
        }
        return baseSoilId;
    }

    public String getLastStep(CodeInfo info) {
        // 获取关联ID
        String lastStep = "";
        if (info.getContent().contains("lastStep")) {
            JSONArray jsonArray = JSONObject.parseArray(info.getContent());
            int size = jsonArray.size();
            for (int i = 0; i < size; i++) {
                String step = jsonArray.getJSONObject(i).get("step").toString();
                if ("subpackage".equals(step)) {
                    lastStep = JSONObject.parseObject(jsonArray.getJSONObject(i).get("info").toString()).get("lastStep").toString();
                }
            }
        }
        return lastStep;
    }

    // 2021-09-02
    @GetMapping(value = "/oldScan/code/{code}")
    public Object newScan(@PathVariable("code") String code, HttpServletRequest request) {
        Box box = boxDao.findBySourceCode(code);
        if (box == null) {
            throw new BusinessException("500", "追溯信息不存在或者未激活");
        }
        JSONObject result = new JSONObject();
        List<String> contents = new ArrayList<>();
        List<CodeInfo> codeInfos = codeInfoDao.findByCode(box.getSubpackageBatch());
        if (codeInfos == null || codeInfos.size() == 0) {
            throw new BusinessException("500", "追溯信息不存在或者未激活");
        } else {
            for (CodeInfo info : codeInfos) {
                contents.add(info.getContent());
                result.put("branch", info.getBranch());
            }
            result.put("infos", contents);
        }
        result.put("company", companyRestService.findById(box.getCompanyId()));
        scanRecordService.save(request, code, box.getCompanyId());
        return result;
    }

    /**
     * 根据二维码查询分包信息
     *
     * @param code
     * @param request
     * @return
     */
    @GetMapping(value = "/sub/{code}")
    public Object subInfo(@PathVariable() String code, HttpServletRequest request) {
        Box box = boxDao.findBySourceCode(code);
        if (box == null) {
            throw new BusinessException("500", "追溯信息不存在或者未激活");
        }
        JSONObject result = new JSONObject();
        Subpackage subpackage = subpackageDao.findByCode(box.getSubpackageId());
        result.put("company", companyRestService.findById(subpackage.getCompanyId()));
        result.put("sub", subpackage);
        return result;
    }


    /**
     * 根据二维码查询扫码信息
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/fromlaststep/{id}")
    public Object scan(@PathVariable("id") String id) {
        List<Subpackage> subpackages = subpackageDao.findByRelevanceId(id);
        if (subpackages.size() == 0) {
            throw new BusinessException("500", "未分包,还未形成追溯信息");
        }
        JSONObject result = new JSONObject();
        List<String> contents = new ArrayList<>();
        Subpackage subpackage = subpackages.get(0);
        List<CodeInfo> codeInfos = codeInfoDao.findByCode(subpackage.getBatch());
        if (codeInfos == null || codeInfos.size() == 0) {
            throw new BusinessException("500", "追溯信息不存在或者未生成");
        } else {
            for (CodeInfo info : codeInfos) {
                contents.add(info.getContent());
                result.put("branch", info.getBranch());
            }
            result.put("infos", contents);
        }
        return result;
    }

    /**
     * 根据二维码查询分包信息
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/sourceinfo", method = RequestMethod.GET)
    public Object sourceIn(HttpServletRequest request) {
        JSONObject result = new JSONObject();
        String sourceCode = request.getParameter("code");
        Subpackage subpackage = subpackageDao.findByCode(sourceCode);
        result.put("company", companyRestService.findById(subpackage.getCompanyId()));
        result.put("sub", subpackage);
        return result;
    }

    /**
     * 扫码记录
     *
     * @param code
     * @return
     */
    @GetMapping(value = "/scanrecords/{code}")
    public Object scanRecord(@PathVariable("code") String code) {
        return success(scanRecordService.list(code));
    }


    /**
     * 根据产品id查询产品
     *
     * @param productId
     * @return
     */
    @GetMapping(value = "/product/{productId}")
    public Object loadProduct(@PathVariable("productId") String productId) {
        return success(productDao.findById(productId));
    }


    /**
     * 企业秀
     *
     * @return
     */
    @GetMapping(value = "/companyshow/{code}")
    public Object companyCode(@PathVariable("code") String code) {
        return companyShowService.show(code);
    }

    /**
     * 地块信息
     *
     * @param basesoidId
     * @return
     */
    @GetMapping(value = "/basesoil/{basesoidId}")
    public Object basesoilInfo(@PathVariable("basesoidId") String basesoidId) {
        return baseSoilService.loadInfo(basesoidId);
    }

    /**
     * 设备信息信息
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/equipment/{id}")
    public Object loadEquipment(@PathVariable("id") String id) {
        return equipmentDao.findById(id);
    }

    /**
     * 加载基源信息
     *
     * @return
     */
    @GetMapping(value = "/jy/{jyId}")
    public Object loadJy(@PathVariable("jyId") String jyId) {
        return modelCropRestService.load(jyId);
    }


    /**
     * 查询12月赋码量
     *
     * @return
     */
    @PostMapping("/uniqueId")
    public Object nuniqueId() {
        return success(scanRecordService.uniqueId(UserAuthUtil.getLoginUser().getCompanyId()));
    }

    /**
     * 查询市扫码分布
     *
     * @return
     */
    @PostMapping("/distribution")
    public Object distribution() {
        return success(scanRecordService.distribution(UserAuthUtil.getLoginUser().getCompanyId()));
    }

    /**
     * 查询省扫码分布
     *
     * @return
     */
    @PostMapping("/omit")
    public Object omit(@RequestBody JSONObject param) {
        List<String> omit = param.getJSONArray("omit").toJavaList(String.class);
        return success(scanRecordService.omit((UserAuthUtil.getLoginUser().getCompanyId()), omit));
    }


}
